#include <cstdio>
#include <cstring>
#include <fstream>
#include "cJSON.h"
#include "conf.h"

using namespace std;

struct conf_cjson_data_t
{
    cJSON *port;
    cJSON *delay_time;
    cJSON *count;
    cJSON *value;
};

struct conf_table_t
{
    int port; // 监听端口
    int delay_time; // 时间间隔，单位秒
    int count; // 判定次数
    int value; // 判定阈值
} table;

/* 解析字符串 */
int conf_parse(const char *json);
/* 打印配置 */
void conf_print();
/* 保存配置 */
void conf_save();

/* 加载配置 */
int conf_load()
{
    /* 加载默认配置 */
    table.port = 8888;
    table.delay_time = 120;
    table.count = 1;
    table.value = 85;

    /* 读取文件到字符串 */
    char *json;
    ifstream file;
    file.open("conf.json", ios::binary);
    file.seekg(0, ios::end);
    int size = file.tellg();
    file.seekg(0, ios::beg);
    json = new char[size + 1];
    file.read(json, size);
    json[size] = '\0';
    file.close();

    conf_parse(json);

    delete[] json;

    return 0;
}

/* 更改配置 */
int conf_change(const char *json)
{
    conf_parse(json);
    conf_save();
    return 0;
}

/* 解析字符串 */
int conf_parse(const char *json)
{
        /* 解析配置 */
    cJSON *json_head = cJSON_Parse(json);

    if(NULL == json_head)
    {
        puts("ERROR: configure parse failed!");
        return -1;
    }

    /* 从json提取值，并执行类型检查 */
    struct conf_cjson_data_t data;
    data.port = cJSON_GetObjectItem(json_head, "port");
    data.delay_time = cJSON_GetObjectItem(json_head, "delay");
    data.count = cJSON_GetObjectItem(json_head, "count");
    data.value = cJSON_GetObjectItem(json_head, "value");

    if(NULL != data.port && cJSON_IsNumber(data.port))
    {
        table.port = cJSON_GetNumberValue(data.port);
    }
    if(NULL != data.delay_time && cJSON_IsNumber(data.delay_time))
    {
        table.delay_time = cJSON_GetNumberValue(data.delay_time);
    }
    if(NULL != data.count && cJSON_IsNumber(data.count))
    {
        table.count = cJSON_GetNumberValue(data.count);
    }
    if(NULL != data.value && cJSON_IsNumber(data.value))
    {
        table.value = cJSON_GetNumberValue(data.value);
    }

    /* 释放json内存 */
    cJSON_Delete(json_head);

    conf_print();

    return 0;
}

/* 打印配置 */
void conf_print()
{
    puts("**************");
    puts("当前运行配置:");
    printf("port = %d\n", table.port);
    printf("delay_time = %d\n", table.delay_time);
    printf("count = %d\n", table.count);
    printf("value = %d\n", table.value);
    puts("**************");
}

/* 保存配置 */
void conf_save()
{
    /* 创建json对象 */
    cJSON *json = cJSON_CreateObject();
    /* 添加节点 */
    cJSON_AddNumberToObject(json, "port", table.port);
    cJSON_AddNumberToObject(json, "delay", table.delay_time);
    cJSON_AddNumberToObject(json, "count", table.count);
    cJSON_AddNumberToObject(json, "value", table.value);
    /* 转换字符串 */
    char *str = cJSON_Print(json);
    /* 写入文件 */
    ofstream file;
    file.open("conf.json", ios::binary);
    file.write(str, strlen(str));
    file.close();
    /* 释放 */
    cJSON_Delete(json);
    free(str);
}

int conf_get_port()
{
    return table.port;
}

int conf_get_delay()
{
    return table.delay_time;
}

int conf_get_count()
{
    return table.count;
}

int conf_get_value()
{
    return table.value;
}